<template>
  <!-- 轮播图组件 -->
  <div class="CarouselItem" :class="{ cardMode: type === 'card' }">
    <div class="container">
      <!-- 每一个图片 -->
      <div class="carouselList">
        <div
          class="imgItem"
          v-for="(item, index) in imgList"
          :key="index"
          :class="{ cardItem: type === 'card' }"
        >
          <div v-if="type === 'card'">
            <img :src="item" alt="" />
          </div>
          <div v-else><img :src="item" alt="" /></div>
        </div>
      </div>

      <!-- 左箭头 -->
      <div class="left">
        <el-icon @click="toLeft" @mouseenter="stop" @mouseout="recover"><ArrowLeft /></el-icon>
      </div>
      <!-- 右箭头 -->
      <div class="right">
        <el-icon @click="toRight" @mouseenter="stop" @mouseout="recover"><ArrowRight /></el-icon>
      </div>
    </div>
  </div>
</template>

<script setup>
import { defineProps, onMounted, onBeforeUnmount } from 'vue'
const props = defineProps({
  imgList: Array,
  type: String
})

let currIndex = 0
if (props.type === 'card') {
  currIndex = 2
}
let count = props.imgList.length
const duration = 3000
let timer

onMounted(() => {
  init()
  if (props.type === 'card') {
    cardCarousel(2)
  }
  startTimer()
})

// 在组件销毁之前清除计时器
onBeforeUnmount(() => {
  clearTimer()

  //销毁组件时，消除visibilitychange
  document.removeEventListener('visibilitychange', handleVisibilityChange)
})

// 初始化
function init() {
  const Carousel = document.querySelector('.CarouselItem')
  const Items = document.querySelector('.carouselList')
  if (props.type !== 'card') {
    const fristItem = Items.firstElementChild.cloneNode(true)
    const lastItem = Items.lastElementChild.cloneNode(true)
    Items.appendChild(fristItem)
    Items.insertBefore(lastItem, Items.firstElementChild)
    lastItem.style.marginLeft = '-100%'
    Carousel.style.overflow = 'hidden'
  } else {
    Items.innerHTML += Items.innerHTML
  }
}

/**
 * 轮播图选择器,输入关键字可以进行布局
 * @param {string} select - 选择器，可以是 'card' 或其他任何字符串
 * @returns {Function} 根据选择返回不同的函数
 */
function CarouselSelector(select) {
  if (select === 'card') {
    return function card(index) {
      const carouselList = document.querySelectorAll('.imgItem')
      if (currIndex > carouselList.length / 2) {
        currIndex = 2
      } else {
        const xOffsetStep = 100 //每个图片的间隔
        const scaleStep = 0.8 //缩放倍率
        const opacitySetp = 0.7
        for (let i = 0; i < carouselList.length; i++) {
          const item = carouselList[i]
          const sign = Math.sign(i - index)
          const dis = Math.abs(i - index)
          const zIndex = carouselList.length - dis
          const scale = scaleStep ** dis
          let xOffset = (i - index) * xOffsetStep
          const opacity = opacitySetp ** dis
          if (i != index) {
            xOffset = xOffset + 200 * sign
          }
          item.style.transform = `translateX(${xOffset}px) scale(${scale})`
          item.style.zIndex = zIndex
          item.style.opacity = opacity
          item.style.transition = `transform 1.5s`
        }
      }
    }
  } else {
    return function layout(index) {
      const carouselItems = document.querySelector('.carouselList')
      if (carouselItems) {
        carouselItems.style.transform = `translateX(-${index * 100}%)`
        carouselItems.style.transition = 'transform 1.5s'
      }
      currIndex = index
    }
  }
}
const cardCarousel = CarouselSelector(props.type)
const layoutCarousel = CarouselSelector('layout')

const toLeft = () => {
  if (props.type === 'card') {
    const carouselItems = document.querySelector('.carouselList')
    const carouselList = document.querySelectorAll('.imgItem')
    const subscript = Math.floor(carouselList.length / 2)

    // 缓存频繁使用的DOM查询结果
    const firstElement = carouselItems.firstElementChild
    const lastElement = carouselList[carouselList.length - 1]
    if (currIndex < subscript) {
      carouselItems.insertBefore(lastElement, firstElement)
      currIndex = subscript - 1
      cardCarousel(currIndex)
    } else {
      cardCarousel(currIndex--)
    }
  } else if (currIndex === 0) {
    const carouselItems = document.querySelector('.carouselList')
    carouselItems.style.transition = 'none'
    carouselItems.style.transform = `translateX(-${count * 100}%)`
    // 等待浏览器渲染
    carouselItems.clientWidth
    layout(count - 1)
  } else {
    layout(currIndex - 1)
  }
}

const toRight = () => {
  if (props.type === 'card') {
    const carouselItems = document.querySelector('.carouselList')
    const carouselList = document.querySelectorAll('.imgItem')
    const i = Math.floor(carouselList.length / 2)
    const fristItem = carouselList[0]
    if (currIndex === i) {
      carouselItems.appendChild(fristItem)
      currIndex = i
      cardCarousel(currIndex)
    } else {
      currIndex++
      cardCarousel(currIndex)
    }
  } else if (currIndex === count - 1) {
    const carouselItems = document.querySelector('.carouselList')
    carouselItems.style.transition = 'none'
    carouselItems.style.transform = `translateX(100%)`
    // 等待浏览器渲染
    carouselItems.clientWidth
    layoutCarousel(0)
  } else {
    layoutCarousel(currIndex + 1)
  }
}

// 启动计时器
const startTimer = () => {
  timer = setInterval(() => {
    toRight()
  }, duration)
}

// 清除计时器
const clearTimer = () => {
  if (timer) {
    clearInterval(timer)
    timer = null
  }
}

const stop = () => {
  clearInterval(timer)
}

const recover = () => {
  startTimer()
}

function handleVisibilityChange() {
  if (document.visibilityState === 'hidden') {
    clearTimer() // 页面隐藏时停止计时器
  } else {
    // 重新启动计时器
    startTimer()
  }
}
document.addEventListener('visibilitychange', handleVisibilityChange)
</script>

<style scoped lang="scss" src="./css/Carousel.scss"></style>
